package com.xxl.vueadmin.controller;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapBuilder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxl.vueadmin.common.Result;
import com.xxl.vueadmin.entity.SysRole;
import com.xxl.vueadmin.entity.SysUser;
import com.xxl.vueadmin.entity.SysUserRole;
import com.xxl.vueadmin.service.ISysUserRoleService;
import com.xxl.vueadmin.utils.Const;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  用户前端控制器
 * </p>
 *
 * @author xu
 * @since 2021-07-28
 */
@RestController
@RequestMapping("/sys/user/")
public class SysUserController extends BaseController {
    @Autowired
    BCryptPasswordEncoder passwordEncoder;

    @Autowired
    ISysUserRoleService userRoleService;

    @GetMapping("info")
    public Result getUserInfo(Principal principal) {
        SysUser user = sysUserService.getBayUserName(principal.getName());
        return Result.success(MapBuilder.create().put("id", user.getId())
                .put("username", user.getUsername())
                .put("avatar", user.getAvatar())
                .put("created", user.getCreated())
                .map());
    }
    @GetMapping("detail/{userId}")
    @PreAuthorize("hasAnyAuthority('sys:user:list')")
    public Result getUserDetail(@PathVariable String userId) {
        SysUser user = sysUserService.getById(userId);
        Assert.notNull(user, "用户不存在");
        List<SysRole> userRoles = sysRoleService.selectUserRoles(user.getId());
        user.setRoles(userRoles);
        return Result.success(user);
    }

    @GetMapping("list")
    @PreAuthorize("hasAnyAuthority('sys:user:list')")
    public Result page(String username) {
        Page<SysUser> userPage = sysUserService.page(getPage(), new QueryWrapper<SysUser>().like(StringUtils.isNotBlank(username), "username", username));
        userPage.getRecords().forEach(user -> {
            user.setRoles(sysRoleService.selectUserRoles(user.getId()));
        });
        return Result.success(userPage);
    }

    @PostMapping("save")
    @PreAuthorize("hasAnyAuthority('sys:user:save')")
    public Result saveUser(@Validated @RequestBody SysUser sysUser) {
        sysUser.setLastLogin(LocalDateTime.now());
        if(StringUtils.isBlank(sysUser.getPassword())) {
            sysUser.setPassword(passwordEncoder.encode(Const.DEFAULT_PASSWORD));
        }else{
            sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        }
        sysUserService.save(sysUser);
        return Result.success("添加成功");
    }

    @PostMapping("edit")
    @PreAuthorize("hasAnyAuthority('sys:user:update')")
    public Result eidtUser(@Validated @RequestBody SysUser sysUser){
        sysUserService.updateById(sysUser);
        return  Result.success("修改成功");
    }

    @PostMapping("permRoles/{userId}")
    @PreAuthorize("hasAnyAuthority('sys:user:role')")
    @Transactional(rollbackFor = RuntimeException.class)
    public Result permRoles(@PathVariable String userId,@RequestBody String[] roleIds){
        userRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", userId));
        List<SysUserRole> userRoles = Stream.of(roleIds).map(roleId -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(roleId);
            sysUserRole.setUserId(userId);
            return sysUserRole;
        }).collect(Collectors.toList());
        userRoleService.saveBatch(userRoles);
        sysUserService.clearUserAuthority(userId);
        return Result.success("修改成功");
    }

    @DeleteMapping("remove")
    @PreAuthorize("hasAnyAuthority('sys:user:delete')")
    @Transactional(rollbackFor = RuntimeException.class)
    public Result removeUser(@RequestBody String[] userIds) {
        List<String> ids = Stream.of(userIds).collect(Collectors.toList());
        ids.forEach(id -> {
            sysUserService.clearUserAuthority(id);
        });
        sysUserService.removeByIds(ids);
        userRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id", ids));

        return  Result.success("删除成功");
    }

    @PostMapping("editPass")
    @PreAuthorize("hasAnyAuthority('sys:user:repass')")
    public Result repass(SysUser sysUser) {
        Assert.notNull(sysUser, "用户信息错误");

        Assert.notBlank(sysUser.getId(), "用户信息错误");
        sysUser.setPassword(passwordEncoder.encode(Const.DEFAULT_PASSWORD));
        if(StringUtils.isBlank(sysUser.getPassword())) {

        }else{

        }
        sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        sysUserService.updateById(sysUser);
        return Result.success("修改成功");
    }
    @PostMapping("repass")
    public Result editPass(@RequestBody SysUser sysUser) {
        Assert.notNull(sysUser, "用户信息错误");

        Assert.notBlank(sysUser.getId(), "用户信息错误");
        sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));

        sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        sysUserService.updateById(sysUser);
        return Result.success("修改成功");
    }
}
